using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SilkSharp
{
	/*
	 * Classes for IIR/FIR resamplers.
	 * 
	 * @author Jing Dai
	 * @author Dingxin Xu
	 */
	public class Silk_resampler_structs
	{
		/**
		 * Flag to enable support for input/output sampling rates above 48 kHz. Turn off for embedded devices.
		 */
		public const int RESAMPLER_SUPPORT_ABOVE_48KHZ = 1;

		public const int SKP_Silk_RESAMPLER_MAX_FIR_ORDER = 16;
		public const int SKP_Silk_RESAMPLER_MAX_IIR_ORDER = 6;
	}

	public class SKP_Silk_resampler_state_struct
	{
		public int[] sIIR = new int[ Silk_resampler_structs.SKP_Silk_RESAMPLER_MAX_IIR_ORDER ];        /* this must be the first element of this struct */
		public int[] sFIR = new int[ Silk_resampler_structs.SKP_Silk_RESAMPLER_MAX_FIR_ORDER ];
		public int[] sDown2 = new int[ 2 ];

		public string str_resampler_function;
		public ResamplerFP resamplerCB;
		public void resampler_function( Object state, short[] _out, int out_offset, short[] _in, int in_offset, int len )
		{
			resamplerCB.resampler_function( state, _out, out_offset, _in, in_offset, len );
		}

		public string str_up2_function;
		public Up2FP up2CB;
		public void up2_function( int[] state, short[] _out, int out_offset, short[] _in, int in_offset, int len )
		{
			up2CB.up2_function( state, _out, out_offset, _in, in_offset, len );

		}

		public int batchSize;
		public int invRatio_Q16;
		public int FIR_Fracs;
		public int input2x;
		public short[] Coefs;

		public int[] sDownPre = new int[ 2 ];
		public int[] sUpPost = new int[ 2 ];

		public string str_down_pre_function;
		public DownPreFP downPreCB;
		public void down_pre_function( int[] state, short[] _out, int out_offset, short[] _in, int in_offset, int len )
		{
			downPreCB.down_pre_function( state, _out, out_offset, _in, in_offset, len );
		}

		public string str_up_post_function;
		public UpPostFP upPostCB;
		public void up_post_function( int[] state, short[] _out, int out_offset, short[] _in, int in_offset, int len )
		{
			upPostCB.up_post_function( state, _out, out_offset, _in, in_offset, len );
		}
		public int batchSizePrePost;
		public int ratio_Q16;
		public int nPreDownsamplers;
		public int nPostUpsamplers;
		public int magic_number;

		/**
		 * set all fields of the instance to zero.
		 */
		public void memZero()
		{
			//		{
			//			if(this.Coefs != null)
			//			{
			//				Arrays.fill(this.Coefs, (short)0);
			//			}
			//		}
			this.Coefs = null;

			Silk_macros.FillArray<int>( this.sDown2, 0 );
			Silk_macros.FillArray<int>( this.sDownPre, 0 );
			Silk_macros.FillArray<int>( this.sFIR, 0 );
			Silk_macros.FillArray<int>( this.sIIR, 0 );
			Silk_macros.FillArray<int>( this.sUpPost, 0 );

			this.batchSize = 0;
			this.batchSizePrePost = 0;
			this.str_down_pre_function = null;
			this.downPreCB = null;
			this.FIR_Fracs = 0;
			this.input2x = 0;
			this.invRatio_Q16 = 0;
			this.magic_number = 0;
			this.nPostUpsamplers = 0;
			this.nPreDownsamplers = 0;
			this.ratio_Q16 = 0;
			this.str_resampler_function = null;
			this.resamplerCB = null;
			this.str_up2_function = null;
			this.up2CB = null;
			this.str_up_post_function = null;
			this.upPostCB = null;
		}
	}

	public interface ResamplerFP
	{
		void resampler_function( Object state, short[] _out, int out_offset, short[] _in, int in_offset, int len );
	}
	public interface Up2FP
	{
		void up2_function( int[] state, short[] _out, int out_offset, short[] _in, int in_offset, int len );
	}
	public interface DownPreFP
	{
		void down_pre_function( int[] state, short[] _out, int out_offset, short[] _in, int in_offset, int len );
	}
	public interface UpPostFP
	{
		void up_post_function( int[] state, short[] _out, int out_offset, short[] _in, int in_offset, int len );
	}
}
